! Project TWS Matrixexponentiële
!
!
! PROGRAM MATRIXEXP
!
! Dit is het hoofdprogramma, info over het gebruik wordt weergegeven met
! matrixexp --help
! 
! @author Roel Matthysen
! @version 2.0
program matrixexp
    use methods
    use IO
    implicit none    
    ! Variabelen die de afhandeling van de algoritmes regelen
    INTEGER :: i,arguments,n, algorithm=1
    CHARACTER(len=32) :: arg
    
    logical :: execute = .true.,verbose = .false.,circulant
    integer, parameter :: doubleprecision = kind(0.d0)
    real(doubleprecision),allocatable :: A(:,:),RES(:,:) 
    real(doubleprecision),allocatable :: Ac(:), RESc(:)
    i = 1
    arguments = command_argument_count()    
    ! Overlopen van alle argumenten    
    do while (i<=arguments)
            CALL get_command_argument(i, arg)
        select case (arg)
                  case('--version')
            write(0,'(a,/,a)') 'versie 2.0','Roel Matthysen (1e Master WIT)'
            ! Als versie wordt opgevraagd wordt het hoofdprogramma niet uitgevoerd
            execute = .false.
        case('--help')
            call displayhelp()
            ! Als de help wordt opgevraagd wordt het hoofdprogramma niet uitgevoerd.
            execute = .false.
        case('--algorithm')
            i = i+1
            call get_command_argument(i,arg)
            select case (arg)
            case('taylor')
                algorithm = 1
            case('eig')
                algorithm = 2
            case('eigqr')
                algorithm = 3
            case default
                write(0,'(3a)') 'Algorithm ',arg,' is not supported'
                execute = .false.
            end select
        case('--verbose')
            verbose = .true.
        case default
            write(0,'(2a)') 'Incorrect parameter ',arg
        end select
        i=i+1
    enddo
    ! Uitvoeren van de berekeningen
    if (execute) then
        ! Circulant of niet
        call iscirculant(5, circulant, n);
        if(circulant) then
            allocate(Ac(n))
            allocate(RESc(n))
            Ac = readmatrixc(n,5)
            select case (algorithm)
            case(1)
                RESc=taylorexpc(Ac,verbose)
            case(2)
                RESc=eigc(Ac,verbose)
            case(3)
                RESc=eigqrc(Ac,verbose)
            case default
            end select
            call printresult(RESc,6)
            deallocate(Ac)
            deallocate(RESc)
        else
            allocate(A(n,n))
            allocate(RES(n,n))
            A = readmatrix(n,5)
            select case (algorithm)
            case(1)
                RES=taylorexp(A,verbose)
            case(2)
                RES=eig(A,verbose)
            case(3)
                RES=eigqr(A,verbose)
            case default
            end select
            call printresult(RES,6)
            deallocate(A)
            deallocate(RES)
        endif
    endif

end program
